﻿// Fill out your copyright notice in the Description page of Project Settings.


#include "Actor/StarrySkyEffectActor.h"

#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystem/StarrySkyAttributeSet.h"
#include "Components/SphereComponent.h"


AStarrySkyEffectActor::AStarrySkyEffectActor()
{
	PrimaryActorTick.bCanEverTick = false;
}

void AStarrySkyEffectActor::BeginPlay()
{
	Super::BeginPlay();
}

void AStarrySkyEffectActor::ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass)
{
	//通过蓝图函数库获取目标角色的AbilitySystemComponent
	UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);
	if (TargetASC==nullptr) return;
	check(GameplayEffectClass);
	//创建游戏效果的上下文
	FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();
	//设置源对象为当前效果
	EffectContextHandle.AddSourceObject(this);
	//创建游戏效果规范
	const FGameplayEffectSpecHandle EffectSpecHandle =TargetASC->MakeOutgoingSpec(GameplayEffectClass, ActorLevel, EffectContextHandle);
	//应用游戏效果
	const FActiveGameplayEffectHandle ActiveEffectHandle = TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());
	//如果使用的效果是持续效果，移除时移除效果
	const bool bIsInfinite =EffectSpecHandle.Data.Get()->Def.Get()->DurationPolicy == EGameplayEffectDurationType::Infinite;
	if (bIsInfinite && InfiniteEffectRemovalPolicy==EEffectRemovalPolicy::RemoveOnEndOverlap)
	{
		ActiveEffectHandles.Add(ActiveEffectHandle,TargetASC);
	}
	//只要不是永久的效果就在应用后销毁
	if (!bIsInfinite)
	{
		Destroy();
	}
}

void AStarrySkyEffectActor::onOverlap(AActor* TargetActor)
{
	//叠加时施加游戏效果，判断叠加效果的策略如果是叠加，则立即生效
	if (InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap)
    {
    	ApplyEffectToTarget(TargetActor,InstantGamePlayEffectClass);
    }
    if (DurationEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap)
    {
    	ApplyEffectToTarget(TargetActor,DurationGamePlayEffectClass);
    }
	//无限效果
    if (InfiniteEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap)
    {
    	ApplyEffectToTarget(TargetActor,InfiniteGamePlayEffectClass);
    }
}

void AStarrySkyEffectActor::onEndOverlap(AActor* TargetActor)
{
	//移除叠加时的效果，判断移除效果的策略
	if (InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap)
	{
		ApplyEffectToTarget(TargetActor,InstantGamePlayEffectClass);
	}
	if (DurationEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap)
	{
		ApplyEffectToTarget(TargetActor,DurationGamePlayEffectClass);
	}
	if (InfiniteEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap)
	{
		ApplyEffectToTarget(TargetActor,InfiniteGamePlayEffectClass);
	}
	//循环变量移除目标的无限效果
	TArray<FActiveGameplayEffectHandle> HandlesToRemove= {};
	//只有无限效果的才进行移除
	if (InfiniteEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap)
	{
		UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);
		if(!IsValid(TargetActor)) return;
		for (TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*> HandlePair : ActiveEffectHandles)
		{
			if (HandlePair.Value == TargetASC)
			{
				TargetASC->RemoveActiveGameplayEffect(HandlePair.Key,1);
				HandlesToRemove.Add(HandlePair.Key);
			}
		}
		for (FActiveGameplayEffectHandle Handle : HandlesToRemove)
		{
			ActiveEffectHandles.FindAndRemoveChecked(Handle);
		}
	}
}

